package top.codestudy.viewtest.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

import top.codestudy.viewtest.R;
import top.codestudy.viewtest.common.Util;

public class NumberProgressBar extends View {
    private String TAG = getClass().getSimpleName();


    private final int default_text_color = Color.rgb(66, 145, 241);
    private final int default_reached_color = Color.rgb(66, 145, 241);
    private final int default_unreached_color = Color.rgb(204, 204, 204);
    private final int default_text_visible = 0;

    private Context context;
    private float default_progress_text_offset;
    private int finishedProgressColor;
    private int unfinishedProgressColor;
    private int textColor;

    private float finishedProgressBarHeight;
    private float unfinishedProgressBarHeight;
    private float textSize;

    private boolean isTextVisibility;
    private int default_text_visibility;

    private int currentProgress;
    private int maxProgress;
    private String currentProgressText;
    private Paint textPaint;
    private Paint finishedPaint;
    private Paint unfinishedPaint;

    /**
     * Unreached bar area to draw rect.
     */
    private RectF mUnreachedRectF = new RectF(0, 0, 0, 0);
    /**
     * Reached bar area rect.
     */
    private RectF mReachedRectF = new RectF(0, 0, 0, 0);

    public NumberProgressBar(Context context) {
        this(context,null);
    }

    public NumberProgressBar(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public NumberProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr,0);
    }

    public NumberProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        this.context = context;
        //1.初始化属性，设置默认值
        initAttribute();
        //2.获取控件布局文件设置的初始值
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NumberProgressBar, defStyleAttr, 0);
        this.finishedProgressColor = typedArray.getColor(R.styleable.NumberProgressBar_progress_reached_color,finishedProgressColor);
        this.unfinishedProgressColor = typedArray.getColor(R.styleable.NumberProgressBar_progress_unreached_color,unfinishedProgressColor);
        this.textColor = typedArray.getColor(R.styleable.NumberProgressBar_progress_text_color,textColor);

        this.textSize = typedArray.getDimension(R.styleable.NumberProgressBar_progress_text_size,textSize);//px
        this.default_progress_text_offset = typedArray.getDimension(R.styleable.NumberProgressBar_progress_text_offset,default_progress_text_offset);//px
        this.finishedProgressBarHeight = typedArray.getDimension(R.styleable.NumberProgressBar_progress_reached_bar_height,finishedProgressBarHeight);
        this.unfinishedProgressBarHeight = typedArray.getDimension(R.styleable.NumberProgressBar_progress_reached_bar_height,unfinishedProgressBarHeight);
        int textVisibility= typedArray.getInt(R.styleable.NumberProgressBar_progress_text_visibility,default_text_visibility);
        if(textVisibility == default_text_visible){
            this.isTextVisibility = true;
        }else {
            this.isTextVisibility = false;
        }
        this.currentProgress = typedArray.getInt(R.styleable.NumberProgressBar_progress_current,currentProgress);
        this.maxProgress = typedArray.getInt(R.styleable.NumberProgressBar_progress_max,maxProgress);
        typedArray.recycle();
        //3.初始化Paint
        initPaint();

    }

    private void initAttribute() {
        this.finishedProgressColor = default_reached_color;
        this.unfinishedProgressColor = default_unreached_color;
        this.textColor = default_text_color;

        this.default_progress_text_offset = Util.dp2px(context,10);
        this.finishedProgressBarHeight = Util.dp2px(context,2f);
        this.unfinishedProgressBarHeight = Util.dp2px(context,1.0f);
        this.textSize = Util.sp2px(context,10);

        this.isTextVisibility = true;
        this.default_text_visibility = default_text_visible;

        this.currentProgress = 0;
        this.maxProgress = 100;
    }

    private void initPaint() {
        textPaint = new Paint();
        textPaint.setAntiAlias(true);
        textPaint.setColor(this.textColor);
        textPaint.setTextSize(this.textSize);

        finishedPaint = new Paint();
        finishedPaint.setAntiAlias(true);
        finishedPaint.setColor(this.finishedProgressColor);

        unfinishedPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        unfinishedPaint.setColor(this.unfinishedProgressColor);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(measure(widthMeasureSpec, true), measure(heightMeasureSpec, false));
    }

    private int measure(int measureSpec, boolean isWidth) {
        int result;
        int mode = MeasureSpec.getMode(measureSpec);
        int size = MeasureSpec.getSize(measureSpec);
        int padding = isWidth ? getPaddingLeft() + getPaddingRight() : getPaddingTop() + getPaddingBottom();
        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else {
            result = isWidth ? getSuggestedMinimumWidth() : getSuggestedMinimumHeight();
            result += padding;
            if (mode == MeasureSpec.AT_MOST) {
                if (isWidth) {
                    result = Math.max(result, size);
                } else {
                    result = Math.min(result, size);
                }
            }
        }
        return result;
    }

    @Override
    protected int getSuggestedMinimumWidth() {
        return (int) textSize;
    }

    @Override
    protected int getSuggestedMinimumHeight() {
        return Math.max((int) textSize, Math.max((int) finishedProgressBarHeight, (int) unfinishedProgressBarHeight));
    }

    private float textStart;
    private float textEnd;
    private boolean mDrawReachedBar;
    private boolean mDrawUnReachedBar;
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //1.计算范围
        currentProgressText = getCurrentProgress() + "%";
        float mDrawTextWidth = textPaint.measureText(currentProgressText);
        if(getCurrentProgress() == 0){
            mDrawReachedBar = false;
            textStart = getPaddingLeft();
        }else {
            mDrawReachedBar = true;
            mReachedRectF.left = getPaddingLeft();
            mReachedRectF.top = getHeight() / 2.0f - finishedProgressBarHeight / 2.0f;
            mReachedRectF.right = (getWidth() - getPaddingLeft() - getPaddingRight()) / (getMaxProgress() * 1.0f) * getCurrentProgress() - default_progress_text_offset + getPaddingLeft();
            mReachedRectF.bottom = getHeight() / 2.0f + finishedProgressBarHeight / 2.0f;
            textStart = mReachedRectF.right + default_progress_text_offset;
        }
        textEnd =(getHeight() / 2.0f) - ((textPaint.descent() + textPaint.ascent()) / 2.0f);

        if ((textStart + mDrawTextWidth) >= getWidth() - getPaddingRight()) {
            textStart = getWidth() - getPaddingRight() - mDrawTextWidth;
            mReachedRectF.right = textStart - default_progress_text_offset;
        }

        float unreachedBarStart = textStart + mDrawTextWidth + default_progress_text_offset;
        if (unreachedBarStart >= getWidth() - getPaddingRight()) {
            mDrawUnReachedBar = false;
        } else {
            mDrawUnReachedBar = true;
            mUnreachedRectF.left = unreachedBarStart;
            mUnreachedRectF.right = getWidth() - getPaddingRight();
            mUnreachedRectF.top = getHeight() / 2.0f + -unfinishedProgressBarHeight / 2.0f;
            mUnreachedRectF.bottom = getHeight() / 2.0f + unfinishedProgressBarHeight / 2.0f;
        }

        if (mDrawReachedBar) {
            canvas.drawRect(mReachedRectF, finishedPaint);
        }

        if (mDrawUnReachedBar) {
            canvas.drawRect(mUnreachedRectF, unfinishedPaint);
        }

        canvas.drawText(currentProgressText, textStart, textEnd, textPaint);

    }


    public int getCurrentProgress() {
        return currentProgress;
    }

    public void setCurrentProgress(int currentProgress) {
        this.currentProgress = currentProgress;
        invalidate();
    }

    public int getMaxProgress() {
        return maxProgress;
    }

    public void setMaxProgress(int maxProgress) {
        this.maxProgress = maxProgress;
        invalidate();
    }
}
